//
//  NSObjcGCD.m
//  高仿暴走斗图
//
//  Created by key on 16/3/22.
//  Copyright © 2016年 huangsongyao. All rights reserved.
//

#import "NSObjcGCD.h"
#import "NSObjcGCD+Manager.h"

static const char *queueChar  =  "com.hsy.Manager";

@implementation NSObjcGCD

#pragma mark - GCD Delay

+ (void)gcd_DelayExecutionForDelayInSeconds:(double)seconds dispatchCompletion:(dispatch_block_t)completion {
    
    // gcd延迟处理
    double delayInSeconds = seconds;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), completion);
}


#pragma mark - GCD CONCURRENT 

+ (void)gcd_GatherThreadForMainQueueBlock:(void(^)())block withGroup:(dispatch_group_t)group {
    
    NSParameterAssert(group);
    // 合并汇总结果
    dispatch_group_t newGroup = group;
    dispatch_group_notify(newGroup, dispatch_get_global_queue(0,0), block);
}

+ (void)gcd_CreateDispatchGroupThreadForParallelQueueBlock:(void(^)())block withGroup:(dispatch_group_t)group {
    
    // 创建单个并行队列
    dispatch_group_async(group, dispatch_get_global_queue(0,0), block);
}

+ (void)gcd_CreateDispatchThreadWithParallelQueues:(NSArray<GCDBlock *> *)queues MainQueueBlock:(void(^)())mainQueueBlock {
    
    if (!queues) {
        return;
    }
    
    // 创建多个并行队列，合并执行
    GCDBlock *block = nil;
    dispatch_group_t group = dispatch_group_create();
    for (NSInteger i = 0; i < queues.count; i ++) {
        
        block = queues[i];
        [NSObjcGCD gcd_CreateDispatchGroupThreadForParallelQueueBlock:block.queueBlock withGroup:group];
    }
    [NSObjcGCD gcd_GatherThreadForMainQueueBlock:mainQueueBlock withGroup:group];
}



#pragma mark - GCD Thread

+ (void)gcd_BackstageExecutionForBlock:(void(^)())block {
    
    // 后台执行
    dispatch_async(dispatch_get_global_queue(0, 0), block);
}

+ (void)gcd_MainThreadExecutionForBlock:(void(^)())block {
    
    // 主线程执行
    dispatch_async(dispatch_get_main_queue(), block);
}


#pragma mark - GCD Queue

+ (void)gcd_CreateQueueForQueueType:(kQueueType)queueType block:(dispatch_block_t)block {
    
    [NSObjcGCD gcd_CreateQueueForChar:queueChar withQueueType:queueType block:block];
}
+ (void)gcd_CreateQueueForChar:(const char *)chars withQueueType:(kQueueType)queueType block:(dispatch_block_t)block {
    
    dispatch_queue_t queue = dispatch_queue_create(chars, [self checkQueueEnumType:queueType]);
    [NSObjcGCD gcd_CreateAsyncQueue:queue withBlock:block];
}

+ (void)gcd_CreateAsyncQueue:(dispatch_queue_t)queue withBlock:(dispatch_block_t)block {
    
    dispatch_async(queue, block);
}


@end


@implementation NSObjcGCD (OperationQueue)

#pragma mark - NSOperationQueue

+ (NSOperationQueue *)gcd_OperationQueueWithSetMaxConcurrentOperationCount:(NSInteger)maxConcurrentOperationCount operations:(NSArray<NSOperation *> *)operations {
    
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = maxConcurrentOperationCount;
    
    for (NSOperation *operation in operations) {
        [queue addOperation:operation];
    }
    
    return queue;
}

+ (NSBlockOperation *)gcd_OpertionWithBlock:(void(^)(void))block operationQueuePriority:(NSOperationQueuePriority)priority andOpertionCompletionBlock:(void(^)(void))completionBlock {
    
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:block];
    
    operation.queuePriority = priority;
    operation.completionBlock = completionBlock;
    
    return operation;
}


@end
